home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
program
/
asm32.zip
/
E32.ZIP
/
SEARCH.ASM
< prev
next >
Wrap
Assembly Source File
|
1996-08-26
|
7KB
|
361 lines
; SEARCH.ASM for E32 - Copyright (C) 1994 - 1996 Douglas Herr
; all rights reserved
include model.inc
; 03/05/1996 DH: calls EDIT_STRING in UTIL.ASM
public search, search_again, replace
extrn locate:near
extrn working:near ; 'Working' message
extrn display_screen:near, display_current:near
extrn close_space:near, open_space:near
extrn rowcount:near
extrn edit_string:near
extrn strlen:near
extrn cursoron:near
extrn keyifwaiting:near, tprintce:near
extrn $strstr:near
extrn $stristr:near
include dataseg.inc
public replace_mode, kbdstat, called_by_menu
extrn filesiz:dword ; size of file
extrn search_start:byte ; flag for top-of-file or cursor start
extrn search_text_buffer:byte, search_text_len:abs, string_edit_data:dword
extrn cursor:dword, inverse:byte, rows:byte
extrn dirty_bits:byte
extrn zero_sel:dword
extrn first_row:byte
kbdstat db 0
find_mess db " Find: ",0
find_mess_len equ ($-find_mess)-1
replace_msg db ' replace? (Yes/No/All)',0
replace_prompt db ' Replace with: ',0
replace_prompt_len equ ($-replace_prompt)-1
replace_mode db 0
called_by_menu db 0
search_len dd 0
replace_len dd 0
bytes_to_add dw 0
was_replaced db 0
extrn cur_posn:word
extrn breakflag:byte
extrn undo_length:word
extrn count_start:dword
extrn file_row:dword
count_bytes equ dword ptr count_start+4
replace_text_len equ 20
replace_text_buffer db (replace_text_len+1) dup(0)
@curseg ends
include codeseg.inc
search_again label proc
clc
call save_offset ; ret: EAX = cursor
mov called_by_menu,0FFh
jmp short _ss0a
;
; This subroutine searches for a string
;
search proc near
mov es,zero_sel
mov dl,es:[417h] ; get kbd status
and dl,11b ; DL <> 0 if shift key pressed
jnz replace ; do REPLACE if SHIFT pressed
clc
call save_offset ; save cursor offset
; ret: EAX = cursor
jc exit
cmp [search_start],'c' ; start at cursor?
je short _ss0a
xor eax,eax
mov count_start,eax
mov file_row,1
dec eax
_ss0a:
mov dword ptr [search_start+1],eax
cmp called_by_menu,0
jne short s0
; get search text if not called from menu
_ss0b:
push ds
pop es
lea edi,string_edit_data
lea eax,search_text_buffer
stosd
mov eax,search_text_len
stosd
lea eax,find_mess
stosd
mov eax,find_mess_len
stosd
call edit_string
cmp ax,27
je exit ; exit if ESC pressed
cmp called_by_menu,0
jne short s0
mov kbdstat,dl ; save keyboard status
s0:
lea ebx,search_text_buffer
call strlen
mov search_len,ecx
jecxz _ss0b
call working ; print 'Working' message
mov edi,dword ptr [search_start+1]
mov esi,ebx
inc edi ; start search one past cursor
push fs
pop es
mov ebx,ecx
mov edx,filesiz
sub edx,edi ; bytes in file to search
jbe short exit
test kbdstat,3 ; Shift key pressed?
jz short s5
call $stristr
jmp short s6
s5:
call $strstr
s6:
jc short exit
add eax,dword ptr [search_start+1]
inc eax
mov cursor,eax
; save bytes to search for rows
mov ecx,eax
sub ecx,count_start
mov count_bytes,ecx
mov dh,rows
sub dh,first_row
shr dh,1
add dh,first_row
mov esi,eax ; cursor
call locate
or dirty_bits,1
call rowcount
exit:
mov called_by_menu,0
clc
ret
search endp
replace_proc equ [ebp-4]
replace proc near
enter 4,0
clc
push [cursor]
push [count_start]
push [file_row]
mov eax,cursor
cmp [search_start],'c' ; start at cursor?
je short r0
xor eax,eax
mov count_start,eax
mov file_row,1
r0:
mov [cursor],eax
call save_offset
; get string to find
r2:
push ds
pop es
lea edi,string_edit_data
lea eax,search_text_buffer
stosd
mov eax,search_text_len
stosd
lea eax,find_mess
stosd
mov eax,find_mess_len
stosd
call edit_string
cmp ax,27
je replace_exit ; exit if ESC pressed
; save keyboard shift status if not called from menu
cmp called_by_menu,0
jne short r2a
mov kbdstat,dl ; save keyboard status
r2a:
lea edi,search_text_buffer
mov ebx,edi
call strlen
mov search_len,ecx
push ds
pop es
lea edi,string_edit_data
lea eax,replace_text_buffer
stosd
mov eax,replace_text_len
stosd
lea eax,replace_prompt
stosd
mov eax,replace_prompt_len
stosd
call edit_string
cmp ax,27
je replace_exit ; exit if ESC pressed
cmp called_by_menu,0
jne short r2b
mov replace_mode,dl ; save keyboard status
r2b:
lea ebx,replace_text_buffer
call strlen
mov replace_len,ecx
sub ecx,search_len ; bytes to add
; negative if file is shortened
; zero if len(search) = len(replace)
mov eax,offset @curseg:same_length
jz short r1a
mov eax,offset @curseg:increase
jns short r1a
mov eax,offset @curseg:decrease
neg cx
r1a: mov replace_proc,eax
mov bytes_to_add,cx
mov breakflag,0 ; zero the ^C flag
r:
call search_again ; search for next occurance
test dirty_bits,1 ; flag set if string found
jz short replace_exit ; exit if not found
call display_screen ; update screen
mov dx,cur_posn
call cursoron
shr breakflag,1
jc short replace_exit
cmp replace_mode,0
jne short _replace_string
lea esi,replace_msg
mov dh,rows
inc dh
xor dl,dl
mov ah,inverse
call tprintce
r3: shr breakflag,1
jc short replace_exit
call keyifwaiting
test ax,ax
jz r3
shr ah,1 ; filter out extended keycodes
jc r3
cmp al,27
je short replace_exit
and al,0FFh-32 ; upper case
cmp al,'Y'
je short _replace_string
cmp al,'N'
je r
cmp al,'A'
jne r3
not replace_mode ; change to continuous
; & fall into _replace_string
_replace_string:
call [replace_proc]
call display_current
and dirty_bits,11111110b
jmp r
replace_exit:
test was_replaced,1
jz short r_exit
mov dh,rows
sub dh,first_row
shr dh,1
add dh,first_row
mov esi,cursor ; cursor
call locate
or dirty_bits,1
jmp short r9
;
; nothing was replaced
;
r_exit:
pop [file_row]
pop [count_start]
pop [cursor]
r9:
clc
leave
ret
replace endp
;
; replace search string at cursor
; called indirectly by replace_proc
;
decrease:
; net file size decrease if len(search) > len(replace)
movzx eax,bytes_to_add ; remove EAX bytes from file
call close_space
jmp short same_length
increase:
; net file size increase if len(search) < len(replace)
movzx eax,bytes_to_add
call open_space
same_length:
; copy replacement string to file
lea esi,replace_text_buffer
mov ecx,replace_len
mov edi,cursor
add cursor,ecx
push fs
pop es
cld
rep movsb
mov was_replaced,1
or dirty_bits,10000000b
ret
;
; save absolute cursor offset for count_start
;
save_offset:
mov eax,cursor
mov count_start,eax
cld
ret
@curseg ends
end